
package states;

import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.state.StateBasedGame;
import org.newdawn.slick.Animation;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.geom.Polygon;
import physics.Block;
import physics.BlockMap;

/**
 *
 * @author wida46061976
 */


public class GamePlaySpaguetiEditionState  extends BasicGameState {
    // Identificador del estat

    public static final int ID = 1;
    // Contenidor d'estats que s'usara per accedir als diferents estats del joc
    private float playerX = 100;
    private float playerY = 20;
    private Animation player;
    private Animation playerR;
    private Animation playerJumpR;
    private Animation playerL;
    private Animation playerJumpL;
    private Animation playerRR;
    private Animation playerRL;
    private Polygon playerPoly;
    public BlockMap map;
    private boolean left = false;
    private boolean isSaltable = true;
    private float[] pos = new float[2];
    private float velX = 0;
    private float velY = 0;
    private float acG = 0.1f;

    @Override
    public int getID() {
        return ID;
    }

    public void init(GameContainer gc, StateBasedGame sbg) throws SlickException {
        map = new BlockMap("resources/mapa02.tmx");
        player = new Animation();
        playerR = new Animation();
        playerR.setAutoUpdate(true);
        playerL = new Animation();
        playerL.setAutoUpdate(true);
        playerJumpR = new Animation();
        playerJumpL = new Animation();
        playerRR = new Animation();
        playerRL = new Animation();

        for (int frame = 0; frame < 4; frame++) {
            playerR.addFrame(new Image("resources/RoSta0" + (frame + 1) + ".png"), 200);
            playerL.addFrame(new Image("resources/RoSta11.png"), 200);
            playerJumpR.addFrame(new Image("resources/RoJum01.png"), 200);
            playerJumpL.addFrame(new Image("resources/RoJum11.png"), 200);
            playerRR.addFrame(new Image("resources/RoRun01.png"), 200);
            playerRL.addFrame(new Image("resources/RoRun11.png"), 200);
        }
        playerPoly = new Polygon(new float[]{
                    playerX + 25, playerY + 27,
                    playerX + 45, playerY + 27,
                    playerX + 45, playerY + 71,
                    playerX + 25, playerY + 71
                });
        player = playerR;
        pos[0] = 0;
        pos[1] = 0;

        posicionarCamara();
        playerPoly.setY(playerY + 27);
        playerPoly.setX(playerX + 25);
    }

    public void render(GameContainer gc, StateBasedGame sbg, Graphics grphcs) throws SlickException {
        BlockMap.tmap.render((int) pos[0], (int) pos[1]);
        grphcs.drawAnimation(player, playerX + (int) pos[0], playerY + (int) pos[1]);
    }

    public void update(GameContainer gc, StateBasedGame sbg, int i) throws SlickException {
        if(gc.getInput().isKeyPressed(Input.KEY_ESCAPE)){
            gc.exit();
        }
        if (gc.getInput().isKeyDown(Input.KEY_LEFT)) {
            left = true;
            velX = -1;
        }
        if (gc.getInput().isKeyDown(Input.KEY_RIGHT)) {
            left = false;
            velX = 1;
        }
        if (gc.getInput().isKeyPressed(Input.KEY_UP)) {
            if (isSaltable) {
                isSaltable = false;
                velY = -3;
            }
        }
        playerY = playerY + distY(velY, i);
        playerPoly.setY(playerY + 27);
        gravity(i);

        playerX = playerX + distX(velX, i);
        playerPoly.setX(playerX + 25);

        posicionarCamara();
        if (velY != 0) {
            if (left == false) {
                player = playerJumpR;
            } else {
                player = playerJumpL;
            }
        } else if (velX != 0) {
            if (left == false) {
                player = playerRR;
            } else {
                player = playerRL;
            }
        } else {
            if (left == false) {
                player = playerR;
            } else {
                player = playerL;
            }
        }
        velX = 0;
    }

    public boolean entityCollisionWith() throws SlickException {
        for (int i = 0; i < BlockMap.entities.size(); i++) {
            Block entity1 = (Block) BlockMap.entities.get(i);
            if (playerPoly.intersects(entity1.poly)) {
                return true;
            }
        }
        return false;
    }

    public void posicionarCamara() {

        if (playerX > 400 / 2 - 40) {
            pos[0] = -(playerX - (400 / 2 - 40));
        } else {
            pos[0] = 0;
        }
        if (playerY > 200 / 2 - 47) {
            pos[1] = -(playerY - (200 / 2 - 47));

        } else {
            pos[1] = 0;
        }


    }
    public void gravity(int delta) {
        try {
            if (velY >= 0) {
                playerPoly.setY(playerY + 27 + 1);
                if (!entityCollisionWith()) {
                    velY = velY + acG * (delta / 10);
                } else {
                    isSaltable = true;
                    velY = 0;
                }
            } else if (velY < 0) {
                playerPoly.setY(playerY + 27 - 1);
                if (!entityCollisionWith()) {
                    velY = velY + acG * (delta / 10);
                } else {
                    velY = 0;
                }
            }
            if(velY>5){
                velY=5;
            }
            if(velY<-5){
                velY=-5;
            }
        } catch (SlickException ex) {
            System.out.println(ex);
        }
        playerPoly.setY(playerY + 27);
    }

    public float distY(float vel, int delta) {
        try {

           float dist =(float) (vel * (delta / 10)+0.5*acG*(delta / 10)*(delta / 10));
            if (dist > 0) {
                for (float i = 0; i <= dist; i=i+0.2f) {
                    playerPoly.setY(playerY + 27 + i +1);
                    if (entityCollisionWith()) {
                        return  i;
                    }
                }
                return dist;
            } else if (dist < 0) {
                for (float i = 0; i >= dist; i=i-0.2f) {
                    playerPoly.setY(playerY + 27 - i -4);
                    if (entityCollisionWith()) {
                        return i;
                    }
                }
                return dist;
            }

        } catch (SlickException ex) {
            System.out.println(ex);
        }
        return 0;
    }

    public float distX(float vel, int delta) {
        try {
            float dist = vel * (delta / 10);
            if (dist > 0) {
                for (float i = 0f; i <= dist; i=i+0.2f) {
                    playerPoly.setX(playerX + 25 + i + 1);
                    if (entityCollisionWith()) {
                        return (float) i;
                    }
                }
                return dist;
            } else if (dist < 0) {
                for (float i = 0f; i >= dist; i=i-0.2f) {
                    playerPoly.setX(playerX + 25 - i -1);
                    if (entityCollisionWith()) {
                        return (float) i;
                    }
                }
                return dist;
            }
            return dist;

        } catch (SlickException ex) {
            System.out.println(ex);
        }
        return 0;
    }
}


